using System;

using FineCollection.Intf;




namespace FineCollection.Immutable
{
    /// <summary>
    /// Immutable empty set. 
    /// </summary>
    /// <typeparam name="T">type of an item.</typeparam>
    public class ImmOrderZero<T> : ImmZero<T>, RRandomSet<T>
        where T: IComparable<T>
    {


        #region CONSTRUCTOR

        private ImmOrderZero() {}


        /// <summary>
        /// An instance of empty set.
        /// </summary>
        new public static readonly ImmOrderZero<T> zero = 
            new ImmOrderZero<T>();

        #endregion


        public T First
        {
            get { throw new CollectionIsEmpty(); }
        }

        public T Last
        {
            get { throw new CollectionIsEmpty(); }
        }


        public int FirstIndex
        {
            get { return 1; }
        }

        public int LastIndex
        {
            get { return 0; }
        }


        public T this[int index]
        {
            get { throw new CollectionIsEmpty(); }
        }


        /// <summary>
        /// Does nothing.
        /// </summary>
        /// <param name="item">an item to look for 
        ///               (it will not be found because the set is empty).</param>
        /// <param name="found">false.</param>
        /// <param name="position">1.</param>
        /// <exception cref="NullItemsException">when the specified item is null.</exception>
        public void Find(T item, out bool found, out int position)
        {
            if (item == null)
                throw new NullItemsException();

            found = false;
            position = FirstIndex;
        }


        /// <summary>
        /// Always does nothing and returns <see cref="int.MinValue"/>.
        /// </summary>
        /// <param name="item">an item to look for 
        ///               (it will not be found because the set is empty).</param>
        /// <returns><see cref="int.MinValue"/>.</returns>
        public int IndexOf(T item)
        {
            return int.MinValue;
        }


        /// <summary>
        /// Creates a read-only ordered iterator.
        /// </summary>
        new public ROrderIterator<T> TakeIterator()
        {
            return orderIteratorOfZero;
        }


        private static readonly OrderIteratorOfZero<T> orderIteratorOfZero = 
            new OrderIteratorOfZero<T>();


        internal class OrderIteratorOfZero<TT> : IteratorOfZero<TT>, ROrderIterator<TT>
            where TT: IComparable<TT>
        {
            public JumpResult Jump(TT item)
            {
                return JumpResult.End;
            }
        }

    }
}